package hust.game.screen;

import hust.game.stages.DragDropStage;

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import server.GameStatus;
import server.ICalculator;
import server.Player;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.Action;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;

public class GameScreen extends AbstractScreen {

	private MyStage stage;
	private Image aim, aimPoint, arrow;
	private Button menu, btnReady, btnStart, btnView, btnExit;
	private Image bia, background, thanhluc, luc;
	private Button bangdiem;
	private BitmapFont mWhiteFont;
	private Label labelAnnounce;
	private Label labelPlayer1, labelPlayer2, labelPlayer3, labelPlayer4;
	private ArrayList<Label> listLabelScore1, listLabelScore2, listLabelScore3,
			listLabelScore4;
	private static boolean start = false;
	private static boolean up = true;
	private static boolean isRunning;
	public static int luotban = 1;
	private float x, y;
	private double rad = 0;
	private static int DIEM;
	private final int Ri = 6;
	private ICalculator objiCalculator;
	private Player player;
	private int i = 0;

	@Override
	public Stage getStage() {
		// TODO Auto-generated method stub
		return stage;
	}

	private static GameScreen instance = null;

	public static Screen getInstance() {
		if (instance == null) {
			instance = new GameScreen();
		}
		return instance;
	}

	public GameScreen() {
		stage = new MyStage() {
			@Override
			public boolean touchDown(int screenX, int screenY, int pointer,
					int button) {
				// TODO Auto-generated method stub
				if (button == Input.Buttons.LEFT) {
					if (isRunning == false) {
						onMouseDown();
					}
				}
				return super.touchDown(screenX, screenY, pointer, button);
			}

			@Override
			public boolean touchUp(int screenX, int screenY, int pointer,
					int button) {
				// TODO Auto-generated method stub
				if (button == Input.Buttons.LEFT) {
					if (isRunning == false) {
						onMouseUp();
					}
				}
				return super.touchUp(screenX, screenY, pointer, button);
			}
		};

		TextureAtlas bgAtlas = game.manager.get("background/background.pack",
				TextureAtlas.class);
		TextureAtlas uiAtlas = game.manager.get("ui/ui.pack",
				TextureAtlas.class);
		TextureAtlas menuAtlas = game.manager.get("ui/menu_bar.pack",
				TextureAtlas.class);

		mWhiteFont = new BitmapFont(
				Gdx.files.internal("font/white_font_26.fnt"),
				uiAtlas.findRegion("white_font_26"), false);

		background = new Image(bgAtlas.findRegion("game_background"));
		background.setFillParent(true);
		stage.addActor(background);

		LabelStyle white = new LabelStyle(mWhiteFont, Color.WHITE);
		labelAnnounce = new Label("Please click ready button to ready!", white);
		// labelAnnounce.setName("lbrd");
		labelAnnounce.setPosition(game.convertWidth(221),
				game.convertHeight(173));
		stage.addActor(labelAnnounce);

		bia = new Image(uiAtlas.findRegion("giado"));
		bia.setPosition(game.convertWidth(402), game.convertHeight(277));
		stage.addActor(bia);

		thanhluc = new Image(uiAtlas.findRegion("progress_out"));
		thanhluc.setPosition(game.convertWidth(749), game.convertHeight(46));
		stage.addActor(thanhluc);

		luc = new Image(uiAtlas.findRegion("progress"));
		luc.setPosition(game.convertWidth(754), game.convertHeight(50));
		stage.addActor(luc);
		luc.setScaleY(0.01f);

		Image bia_ngam = new Image(uiAtlas.findRegion("bia_diem"));
		bia_ngam.setPosition(game.convertWidth(398), game.convertHeight(306));
		bia_ngam.setSize(64, 64);
		stage.addActor(bia_ngam);

		aim = new Image(uiAtlas.findRegion("vong_ngam")) {
			@Override
			public Actor hit(float x, float y, boolean touchable) {
				// TODO Auto-generated method stub
				// return super.hit(x, y, touchable);
				return null;
			}
		};
		stage.addActor(aim);

		aimPoint = new Image(uiAtlas.findRegion("tam_ngam"));
		stage.addActor(aimPoint);
		aimPoint.setOrigin(-0.5f, -0.5f);

		arrow = new Image(uiAtlas.findRegion("ten")) {
			@Override
			public Actor hit(float x, float y, boolean touchable) {
				// TODO Auto-generated method stub
				return super.hit(x, y, touchable);
				// return null;
			}
		};

		arrow.setName("Ten");
		arrow.setPosition(game.convertWidth(480), game.convertHeight(0));
		stage.addActor(arrow);

		arrow.setVisible(true);
		// Menu bar
		menu = new Button(new TextureRegionDrawable(
				menuAtlas.findRegion("dialog_btn_show")));
		menu.setPosition(game.convertWidth(0), game.convertHeight(21));
		stage.addActor(menu);

		btnReady = new Button(new TextureRegionDrawable(
				menuAtlas.findRegion("btn_ready")));
		btnReady.setPosition(game.convertWidth(10), game.convertHeight(253));
		// btnReady.setName("re");
		stage.addActor(btnReady);

		btnStart = new Button(new TextureRegionDrawable(
				menuAtlas.findRegion("btn_start")));
		btnStart.setPosition(game.convertWidth(10), game.convertHeight(183));
		// btnStart.setName("sa");
		stage.addActor(btnStart);

		btnView = new Button(new TextureRegionDrawable(
				menuAtlas.findRegion("btn_view")));
		btnView.setPosition(game.convertWidth(10), game.convertHeight(113));
		// btnView.setName("vi");
		stage.addActor(btnView);

		btnExit = new Button(new TextureRegionDrawable(
				menuAtlas.findRegion("btn_exit")));
		btnExit.setPosition(game.convertWidth(10), game.convertHeight(43));
		// btnExit.setName("ex");
		stage.addActor(btnExit);

		player = new Player();

		bangdiem = new Button(new TextureRegionDrawable(
				menuAtlas.findRegion("mark_record")));
		bangdiem.setPosition(game.convertWidth(194), game.convertHeight(276));
		stage.addActor(bangdiem);
		bangdiem.setVisible(false);
		labelPlayer1 = new Label("Player 1", white);
		labelPlayer2 = new Label("Player 2", white);
		labelPlayer3 = new Label("Player 3", white);
		labelPlayer4 = new Label("Player 4", white);
		listLabelScore1 = new ArrayList<Label>();
		listLabelScore2 = new ArrayList<Label>();
		listLabelScore3 = new ArrayList<Label>();
		listLabelScore4 = new ArrayList<Label>();

		bangdiem.addActor(labelPlayer1);
		bangdiem.addActor(labelPlayer2);
		bangdiem.addActor(labelPlayer3);
		bangdiem.addActor(labelPlayer4);
		labelPlayer1
				.setPosition(game.convertWidth(38), game.convertHeight(146));
		labelPlayer2
				.setPosition(game.convertWidth(38), game.convertHeight(103));
		labelPlayer3.setPosition(game.convertWidth(38), game.convertHeight(60));
		labelPlayer4.setPosition(game.convertWidth(38), game.convertHeight(17));
		for (int i = 0; i < 3; i++) {
			listLabelScore1.add(new Label("1", white));
			bangdiem.addActor(listLabelScore1.get(i));
		}
		for (int i = 0; i < 3; i++) {
			listLabelScore2.add(new Label("1", white));
			bangdiem.addActor(listLabelScore2.get(i));
		}
		for (int i = 0; i < 3; i++) {
			listLabelScore3.add(new Label("1", white));
			bangdiem.addActor(listLabelScore3.get(i));
		}
		for (int i = 0; i < 3; i++) {
			listLabelScore4.add(new Label("1", white));
			bangdiem.addActor(listLabelScore4.get(i));
		}

		listLabelScore1.get(0).setPosition(174, labelPlayer1.getY());
		listLabelScore1.get(1).setPosition(264, labelPlayer1.getY());
		listLabelScore1.get(2).setPosition(344, labelPlayer1.getY());
		listLabelScore2.get(0).setPosition(174, labelPlayer2.getY());
		listLabelScore2.get(1).setPosition(264, labelPlayer2.getY());
		listLabelScore2.get(2).setPosition(344, labelPlayer2.getY());
		listLabelScore3.get(0).setPosition(174, labelPlayer3.getY());
		listLabelScore3.get(1).setPosition(264, labelPlayer3.getY());
		listLabelScore3.get(2).setPosition(344, labelPlayer3.getY());
		listLabelScore4.get(0).setPosition(174, labelPlayer4.getY());
		listLabelScore4.get(1).setPosition(264, labelPlayer4.getY());
		listLabelScore4.get(2).setPosition(344, labelPlayer4.getY());

		btnReady.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				super.clicked(event, x, y);
				try {
					objiCalculator = (ICalculator) Naming.lookup("rmi://192.168.1.136:1099/CalculatorTest");
					labelAnnounce.setText("Please click start button to start game");
					player = objiCalculator.connect();
					// btnReady.setVisible(false);
				} catch (Exception e) {
//					JOptionPane.showMessageDialog(null,	"Khong ket noi duoc den server");
					int res = JOptionPane.showOptionDialog(null, "Khong ket noi duoc den server", "", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null);
					System.out.println("Ok click 5");
					if(res == 0){
						game.setScreen(new HomeScreen());
					}
				}

			}
		});

		btnStart.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				super.clicked(event, x, y);
				if(objiCalculator !=null)
				try {
					if (objiCalculator.getListPlayer().size() >= 2) {
						objiCalculator.setStatus(GameStatus.RUNNING);
					} else {
						labelAnnounce.setText("Waiting for other players join the game!");
					}
				} catch (RemoteException e) {
					// TODO Auto-generated catch block
//					JOptionPane.showMessageDialog(null,	"Khong ket noi duoc den server");
					int res = JOptionPane.showOptionDialog(null, "Khong ket noi duoc den server", "", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null);
					System.out.println("Ok click 6");
					if(res == 0){
						game.setScreen(new HomeScreen());
					}
				}

			}
		});

		btnView.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				super.clicked(event, x, y);
				if (i == 0) {
					bangdiem.setVisible(true);
					for (int j = 0; j < bangdiem.getChildren().size; j++) {
						bangdiem.getChildren().get(j).setVisible(false);
					}
					try {
						ArrayList<Player> listPlayer;
						if (objiCalculator == null) {
							JOptionPane.showMessageDialog(null,
									"Chua ket noi duoc den server");

						} else {
							listPlayer = objiCalculator.getListPlayer();
							switch (listPlayer.size()) {
							case 2:
								labelPlayer1.setVisible(true);
								labelPlayer2.setVisible(true);
								for(int i = 0; i < listPlayer.get(0).listPoint.size(); i++){
									listLabelScore1.get(i).setVisible(true);
									listLabelScore1.get(i).setText(listPlayer.get(0).listPoint.get(i).toString());
								}
								for(int i = 0; i < listPlayer.get(1).listPoint.size(); i++){
									listLabelScore2.get(i).setVisible(true);
									listLabelScore2.get(i).setText(listPlayer.get(1).listPoint.get(i).toString());
								}
								break;
							case 3:
								labelPlayer1.setVisible(true);
								labelPlayer2.setVisible(true);
								labelPlayer3.setVisible(true);
								for(int i = 0; i < listPlayer.get(0).listPoint.size(); i++){
									listLabelScore1.get(i).setVisible(true);
									listLabelScore1.get(i).setText(listPlayer.get(0).listPoint.get(i).toString());
								}
								for(int i = 0; i < listPlayer.get(1).listPoint.size(); i++){
									listLabelScore2.get(i).setVisible(true);
									listLabelScore2.get(i).setText(listPlayer.get(1).listPoint.get(i).toString());
								}
								for(int i = 0; i < listPlayer.get(2).listPoint.size(); i++){
									listLabelScore3.get(i).setVisible(true);
									listLabelScore3.get(i).setText(listPlayer.get(2).listPoint.get(i).toString());
								}
								break;
							case 4:
								labelPlayer1.setVisible(true);
								labelPlayer2.setVisible(true);
								labelPlayer3.setVisible(true);
								labelPlayer4.setVisible(true);
								for(int i = 0; i < listPlayer.get(0).listPoint.size(); i++){
									listLabelScore1.get(i).setVisible(true);
									listLabelScore1.get(i).setText(listPlayer.get(0).listPoint.get(i).toString());
								}
								for(int i = 0; i < listPlayer.get(1).listPoint.size(); i++){
									listLabelScore2.get(i).setVisible(true);
									listLabelScore2.get(i).setText(listPlayer.get(1).listPoint.get(i).toString());
								}
								for(int i = 0; i < listPlayer.get(2).listPoint.size(); i++){
									listLabelScore3.get(i).setVisible(true);
									listLabelScore3.get(i).setText(listPlayer.get(2).listPoint.get(i).toString());
								}
								for(int i = 0; i < listPlayer.get(3).listPoint.size(); i++){
									listLabelScore4.get(i).setVisible(true);
									listLabelScore4.get(i).setText(listPlayer.get(3).listPoint.get(i).toString());
								}

								break;
							default:
								break;
							}
						}
					} catch (RemoteException e) {
//						JOptionPane.showMessageDialog(null,	"Khong ket noi duoc den server");
						int res = JOptionPane.showOptionDialog(null, "Khong ket noi duoc den server", "", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null);
						System.out.println("Ok click 7");
						if(res == 0){
							game.setScreen(new HomeScreen());
						}
					}
					i++;
				} else {
					bangdiem.setVisible(false);
					i--;
				}
			}
		});

	}

	@Override
	public void render(float delta) {
		super.render(delta);
		aim.setPosition( game.convertWidth(Gdx.input.getX() - aim.getWidth() / 2),	game.convertHeight(480 - Gdx.input.getY() - aim.getHeight() / 2));
		if (isRunning == false) {
			aimPoint.setPosition(Gdx.input.getX() - aimPoint.getWidth() / 2,	480 - Gdx.input.getY() - aimPoint.getHeight() / 2);
		}
		
		try {
			if (objiCalculator != null) {
				if (objiCalculator.getStatus() == GameStatus.RUNNING) {
					btnReady.setVisible(false);
					btnStart.setVisible(false);
					labelAnnounce.setVisible(false);
					
					
					aimMove();
					progressbar();
				
				}
				if(player.ordinalNumber == objiCalculator.getTurn() && objiCalculator.getStatus() == GameStatus.RUNNING){
					btnView.setVisible(false);
				}
				else{
					btnView.setVisible(true);
				}
				if(luotban == 4){
					int res = JOptionPane.showOptionDialog(null, "Winner", "Ban da chien thang", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null);
					if(res == 0){
						game.setScreen(new HomeScreen());
					}
				}
			}
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			int res = JOptionPane.showOptionDialog(null, "Khong ket noi duoc den server", "", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null);
			System.out.println("Ok click 1");
			if(res == 0){
				game.setScreen(new HomeScreen());
			}
				
		}

	}

	public void aimMove() {
		if (start == true) {
			rad++;
			getPosX();
			getPosY();
			aimPoint.setPosition(game.convertWidth(x), game.convertHeight(y));
		}
	}

	public void progressbar() {
		if (start == true) {
			if (up == true) {
				if (luc.getScaleY() <= 1) {
					luc.scale(0, 0.02f);
				} else {
					up = false;
				}
			} else {
				if (luc.getScaleY() > 0.01f) {
					luc.scale(0, -0.02f);
				} else {
					up = true;
				}
			}
		}
	}

	public void checkDIEM() {
		// tam cua bia co toa do 430x142 (do toa do anh y la 480-306)
		double a = Math.abs(Gdx.input.getX() - 430);
		double b = Math.abs(Gdx.input.getY() - 142);
		double R = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
		if ((R >= 0) && (R < 3)) {
			DIEM = 10;
		} else if ((R >= 3) && (R < 5)) {
			DIEM = 9;
		} else if ((R >= 5) && (R < 9)) {
			DIEM = 8;
		} else if ((R >= 9) && (R < 14)) {
			DIEM = 7;
		} else if ((R >= 14) && (R < 17)) {
			DIEM = 6;
		} else if ((R >= 17) && (R < 20)) {
			DIEM = 5;
		} else if ((R >= 20) && (R < 23)) {
			DIEM = 4;
		} else if ((R >= 23) && (R < 26)) {
			DIEM = 3;
		} else if ((R >= 26) && (R < 29)) {
			DIEM = 2;
		} else if ((R >= 29) && (R <= 32)) {
			DIEM = 1;
		} else {
			DIEM = 0;
		}
		System.out.println("Diem: " + DIEM);
		luotban++;
		System.out.println("Luot ban: " + luotban);
		try {
			objiCalculator.addPoint(player.ipAddress, DIEM);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
//			JOptionPane.showMessageDialog(null, "Khong ket noi duoc den server");
			int res = JOptionPane.showOptionDialog(null, "Khong ket noi duoc den server", "", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null);
			System.out.println("Ok click 2");
			if(res == 0){
				game.setScreen(new HomeScreen());
			}
		}
	}

	public void onMouseDown() {
		// aimPoint.addAction(Actions.rotateBy(36000, 200));

		try {
			if (objiCalculator != null)
				if (objiCalculator.getTurn() == player.ordinalNumber
						&& objiCalculator.getStatus() == GameStatus.RUNNING) {
					luc.setScaleY(0.01f);
					resetArrow();
					start = true;
				}
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
//			JOptionPane.showMessageDialog(null, "Khong ket noi duoc den server");
			int res = JOptionPane.showOptionDialog(null, "Khong ket noi duoc den server", "", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null);
			System.out.println("Ok click 3");
			if(res == 0){
				game.setScreen(new HomeScreen());
			}
		}
	}

	public void onMouseUp() {
		try {
			if (objiCalculator != null)
				if (objiCalculator.getTurn() == player.ordinalNumber
						&& objiCalculator.getStatus() == GameStatus.RUNNING && luotban <=3) {
//					resetArrow();
					aimPoint.clearActions();
					start = false;
					float duration = 1.5f - luc.getScaleY();
					if (duration <= 1.2f) {
						arrow.setVisible(true);
						arrow.addAction(Actions.sequence(
								Actions.moveTo(aimPoint.getX(), aimPoint.getY()	- arrow.getHeight(), duration),
								new Action() {
									@Override
									public boolean act(float delta) {
										// TODO Auto-generated method stub
										isRunning = false;
										return true;
									}
								}));
						isRunning = true;
						// Server xu ly
						luotban++;
					}
					checkDIEM();
				}
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
//			JOptionPane.showMessageDialog(null, "Khong ket noi duoc den server");
			int res = JOptionPane.showOptionDialog(null, "Khong ket noi duoc den server", "", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null);
			System.out.println("Ok click 4");
			if(res == 0){
				game.setScreen(new HomeScreen());
			}
		}
	}

	public void resetArrow() {
		arrow.setPosition(game.convertWidth(480), game.convertHeight(-50));
		arrow.setVisible(false);
	}

	public float getPosX() {
		// tam la toa do chuot, ban kinh = 5
		if (rad > 360) {
			rad = rad - 360;
		}

		if ((rad > 0) && (rad <= 90)) {
			x = (float) Math.sin(rad * Math.PI / 180) * Ri;
			x = Gdx.input.getX() + x - aimPoint.getWidth() / 2;
		} else if ((rad > 90) && (rad <= 180)) {
			x = (float) Math.sin(rad * Math.PI / 180) * Ri;
			x = Gdx.input.getX() + x - aimPoint.getWidth() / 2;
		} else if ((rad > 180) && (rad <= 270)) {
			x = (float) Math.sin(rad * Math.PI / 180) * Ri;
			x = Gdx.input.getX() + x - aimPoint.getWidth() / 2;
		} else if ((rad > 270) && (rad <= 360)) {
			x = (float) Math.sin(rad * Math.PI / 180) * Ri;
			x = Gdx.input.getX() + x - aimPoint.getWidth() / 2;
		}

		return x;
	}

	public float getPosY() {
		// tam la toa do chuot, ban kinh = 5
		if (rad > 360) {
			rad = rad - 360;
		}

		if ((rad > 0) && (rad <= 90)) {
			y = (float) Math.cos(rad * Math.PI / 180) * Ri;
			y = 480 - Gdx.input.getY() - y - aimPoint.getHeight() / 2;
		} else if ((rad > 90) && (rad <= 180)) {
			y = (float) Math.cos(rad * Math.PI / 180) * Ri;
			y = 480 - Gdx.input.getY() - y - aimPoint.getHeight() / 2;
		} else if ((rad > 180) && (rad <= 270)) {
			y = (float) Math.cos(rad * Math.PI / 180) * Ri;
			y = 480 - Gdx.input.getY() - y - aimPoint.getHeight() / 2;
		} else if ((rad > 270) && (rad <= 360)) {
			y = (float) Math.cos(rad * Math.PI / 180) * Ri;
			y = 480 - Gdx.input.getY() - y - aimPoint.getHeight() / 2;
		}

		return y;
	}

	class MyStage extends DragDropStage {

		public MyStage() {
			super(game.assumeWidth, game.assumeHeight, false);
			// TODO Auto-generated constructor stub
		}
	}

}
